/* 
 * File:   SkinFactory.cpp
 * Author: lgr013
 * 
 * Created on 7 de septiembre de 2014, 13:23
 */

#include <Box2D/Common/b2Math.h>

#include "SkinFactory.h"

SkinFactory::SkinFactory() {
}

SkinFactory::SkinFactory(SDL_Renderer *gRenderer, int pixelWidth, int pixelHeight, int unitWidth, int unitHeight) {
    this->setGameRenderer(gRenderer);
    this->pixelWidth = pixelWidth;
    this->pixelHeight = pixelHeight;
    this->unitWidth = unitWidth;
    this->unitHeight = unitHeight;
    this->border = 200;
    this->viewport.x = (border / 2);
    this->viewport.y = (border / 2);
    this->viewport.w = unitWidth;
    this->viewport.h = unitHeight;
    myLogFile->getInstance(MY_LOG_MODE);
}

SkinFactory::~SkinFactory() {
    cout << "Destructor de SkinFactory \n";
}

void SkinFactory::setCenterX(int centerx) {
    centerX = centerx;
}

void SkinFactory::setCenterY(int centery) {
    centerY = centery;
}

void SkinFactory::setSideBase(int sidebases) {
    sideBase = sidebases;
}

void SkinFactory::setSideBaseMin(int sidebasemin) {
    sideBaseMin = sidebasemin;
}

void SkinFactory::setSideHeight(int sideheight) {
    sideHeight = sideheight;
}

void SkinFactory::setSideQuantity(int n) {
    sideQuantity = n;
}

void SkinFactory::setEscale(int eskale) {
    escale = eskale;
}

void SkinFactory::setAngle1(double myangle) {
    angle1 = myangle;
}

void SkinFactory::setAngle2(double myangle) {
    angle2 = myangle;
}

void SkinFactory::setGameRenderer(SDL_Renderer* grenderer) {
    gameRenderer = grenderer;
}

void SkinFactory::setRColor(Uint8 rcolor) {
    redColor = rcolor;
}

void SkinFactory::setGColor(Uint8 gcolor) {
    greenColor = gcolor;
}

void SkinFactory::setBColor(Uint8 bcolor) {
    blueColor = bcolor;
}

void SkinFactory::setAColor(Uint8 acolor) {
    alphaColor = acolor;
}

int SkinFactory::getCenterX() {
    int posx;
    posx = this->centerX;
    return posx;
}

int SkinFactory::getCenterY() {
    int posy;
    posy = this->centerY;
    return posy;
}

int SkinFactory::getSideBase() {
    int side;
    side = this->sideBase;
    return side;
}

int SkinFactory::getSideBaseMin() {
    int side;
    side = this->sideBaseMin;
    return side;
}

int SkinFactory::getSideHeight() {
    int side;
    side = this->sideHeight;
    return side;
}

SDL_Renderer* SkinFactory::getGameRenderer() {
    SDL_Renderer* grenderer;
    grenderer = this->gameRenderer;
    return grenderer;
}

Uint8 SkinFactory::getRColor() {
    Uint8 rcolor;
    rcolor = this->redColor;
    return rcolor;
}

Uint8 SkinFactory::getGColor() {
    Uint8 gcolor;
    gcolor = this->greenColor;
    return gcolor;
}

Uint8 SkinFactory::getBColor() {
    Uint8 bcolor;
    bcolor = this->blueColor;
    return bcolor;
}

Uint8 SkinFactory::getAColor() {
    Uint8 acolor;
    acolor = this->alphaColor;
    return acolor;
}

bool SkinFactory::makeRectangle(b2Vec2 *pos, b2Vec2 *size, float rotation, Uint8 r, Uint8 g, Uint8 b, Uint8 a) {
    bool success = true;
    float32 cornerx, cornery;
    cornerx = pos->x - size->x / 2;
    cornery = pos->y - size->y / 2;
    float angle = rotation * 57; // radianes * 57 = grados

    SDL_Point center = {(int) pos->x, (int) pos->y};
    SDL_Rect fillRectangle = {(int) cornerx, (int) cornery, (int) size->x, (int) size->y};

    SDL_Texture* mTexture = SDL_CreateTexture(this->gameRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, unitWidth, unitHeight);
    SDL_SetRenderTarget(this->gameRenderer, mTexture);
    SDL_SetRenderDrawBlendMode(this->gameRenderer, SDL_BLENDMODE_BLEND);
    SDL_SetTextureBlendMode(mTexture, SDL_BLENDMODE_BLEND);
    SDL_SetRenderDrawColor(this->gameRenderer, 0xFF, 0xFF, 0xAA, SDL_BLENDMODE_NONE);
    SDL_RenderClear(this->gameRenderer);

    SDL_SetRenderDrawColor(this->gameRenderer, r, g, b, a);
    if (SDL_RenderFillRect(this->gameRenderer, &fillRectangle) < 0) {
        string lineToLog = "";
        string error(SDL_GetError());
        lineToLog = "[2] SDL no pudo dibujar el rectángulo. Error: " + error + "\n";
        myLogFile->writeInLog(2, lineToLog);
        success = false;
    } else {
        SDL_SetRenderTarget(this->gameRenderer, NULL);
        SDL_Texture* mTexture2 = SDL_CreateTexture(this->gameRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, unitWidth, unitHeight);
        SDL_SetRenderTarget(this->gameRenderer, mTexture2);
        //        SDL_SetRenderDrawBlendMode(this->gameRenderer, SDL_BLENDMODE_BLEND);
        SDL_SetTextureBlendMode(mTexture2, SDL_BLENDMODE_BLEND);
        SDL_SetRenderDrawColor(this->gameRenderer, 0xFF, 0xFF, 0xAA, SDL_BLENDMODE_NONE);
        SDL_RenderClear(this->gameRenderer);
        SDL_RenderCopyEx(this->gameRenderer, mTexture, NULL, NULL, angle, &center, SDL_FLIP_NONE);
        SDL_SetRenderTarget(this->gameRenderer, NULL);
        //        SDL_RenderCopy(this->gameRenderer, mTexture2, &viewport, NULL);
        SDL_RenderCopyEx(this->gameRenderer, mTexture2, NULL, NULL, 0, &center, SDL_FLIP_NONE);
        SDL_DestroyTexture(mTexture2);
        mTexture2 = NULL;
    }
    SDL_DestroyTexture(mTexture);
    mTexture = NULL;
    return success;
}

bool SkinFactory::makePolygon(b2Vec2* pos, int n, int escale, float rotation, Uint8 r, Uint8 g, Uint8 b, Uint8 a) {
    bool success = true;
    int side;
    float angle = rotation * 57;
    SDL_Point center = {(int) pos->x + (border / 2), (int) pos->y + (border / 2)};

    float x, y;
    side = ((2 * escale) * sin(M_PI / n));
    short vx[n], vy[n];
    for (int i = 0; i < n; ++i) {
        x = pos->x + side * cos(2 * M_PI * i / n);
        y = pos->y + side * sin(2 * M_PI * i / n);
        vx[i] = x + (border / 2);
        vy[i] = y + (border / 2);
    }
    SDL_Texture* mTexture = SDL_CreateTexture(this->gameRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, unitWidth + border, unitHeight + border);
    SDL_SetRenderTarget(this->gameRenderer, mTexture);
    //    SDL_SetRenderDrawBlendMode(this->gameRenderer, SDL_BLENDMODE_BLEND);
    SDL_SetTextureBlendMode(mTexture, SDL_BLENDMODE_BLEND);
    SDL_SetRenderDrawColor(this->gameRenderer, 0xFF, 0xFF, 0xAA, SDL_BLENDMODE_NONE);
    SDL_RenderClear(this->gameRenderer);
    if (filledPolygonRGBA(this->gameRenderer, vx, vy, n, r, g, b, a) < 0) {
        string lineToLog = "";
        string error(SDL_GetError());
        lineToLog = "[2] SDL no pudo dibujar el polígono. Error: " + error + "\n";
        myLogFile->writeInLog(2, lineToLog);
        success = false;
    } else {
        SDL_SetRenderTarget(this->gameRenderer, NULL);
        SDL_Texture* mTexture2 = SDL_CreateTexture(this->gameRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, unitWidth + border, unitHeight + border);
        SDL_SetRenderTarget(this->gameRenderer, mTexture2);
        //        SDL_SetRenderDrawBlendMode(this->gameRenderer, SDL_BLENDMODE_BLEND);
        SDL_SetTextureBlendMode(mTexture2, SDL_BLENDMODE_BLEND);
        SDL_SetRenderDrawColor(this->gameRenderer, 0xFF, 0xFF, 0xAA, SDL_BLENDMODE_NONE);
        SDL_RenderClear(this->gameRenderer);
        SDL_RenderCopyEx(this->gameRenderer, mTexture, NULL, NULL, angle, &center, SDL_FLIP_NONE);
        SDL_SetRenderTarget(this->gameRenderer, NULL);
        SDL_RenderCopy(this->gameRenderer, mTexture2, &viewport, NULL);
        SDL_DestroyTexture(mTexture2);
        mTexture2 = NULL;
    }
    SDL_DestroyTexture(mTexture);
    mTexture = NULL;
    return success;
}

bool SkinFactory::makeCircle(b2Vec2* pos, int radius, float rotation, Uint8 r, Uint8 g, Uint8 b, Uint8 a) {

    bool success = true;
    b2Vec2 size(50 * radius / 100, 50 * radius / 100);

    float32 cornerx, cornery;
    cornerx = pos->x - size.x / 2;
    cornery = pos->y - size.y / 2;
    SDL_Rect fillRectangle = {(int) cornerx, (int) cornery, (int) size.x, (int) size.y};

    float angle = rotation * 57; // radianes * 57 = grados
    SDL_Point center = {(int) pos->x, (int) pos->y};


    SDL_Texture* mTexture = SDL_CreateTexture(this->gameRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, unitWidth, unitHeight);
    SDL_SetRenderTarget(this->gameRenderer, mTexture);
    //    SDL_SetRenderDrawBlendMode(this->gameRenderer, SDL_BLENDMODE_BLEND);
    SDL_SetTextureBlendMode(mTexture, SDL_BLENDMODE_BLEND);
    SDL_SetRenderDrawColor(this->gameRenderer, 0xFF, 0xFF, 0xAA, SDL_BLENDMODE_NONE);
    SDL_RenderClear(this->gameRenderer);
    if (filledCircleRGBA(this->gameRenderer, pos->x, pos->y, radius, r, g, b, a) < 0) {
        string lineToLog = "";
        string error(SDL_GetError());
        lineToLog = "[2] SDL no pudo dibujar el círculo. Error: " + error + "\n";
        myLogFile->writeInLog(2, lineToLog);
        success = false;
    } else {
        SDL_SetRenderDrawColor(this->gameRenderer, 0x1A, 0xAF, 0xA6, a);
        SDL_RenderFillRect(this->gameRenderer, &fillRectangle);
        SDL_SetRenderTarget(this->gameRenderer, NULL);
        SDL_Texture* mTexture2 = SDL_CreateTexture(this->gameRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, unitWidth, unitHeight);
        SDL_SetRenderTarget(this->gameRenderer, mTexture2);
        //        SDL_SetRenderDrawBlendMode(this->gameRenderer, SDL_BLENDMODE_BLEND);
        SDL_SetTextureBlendMode(mTexture2, SDL_BLENDMODE_BLEND);
        SDL_SetRenderDrawColor(this->gameRenderer, 0xFF, 0xFF, 0xAA, SDL_BLENDMODE_NONE);
        SDL_RenderClear(this->gameRenderer);
        SDL_RenderCopyEx(this->gameRenderer, mTexture, NULL, NULL, angle, &center, SDL_FLIP_NONE);
        SDL_SetRenderTarget(this->gameRenderer, NULL);
        SDL_RenderCopyEx(this->gameRenderer, mTexture2, NULL, NULL, 0, &center, SDL_FLIP_NONE);
        SDL_DestroyTexture(mTexture2);
        mTexture2 = NULL;
    }
    SDL_DestroyTexture(mTexture);
    mTexture = NULL;
    return success;
}

bool SkinFactory::makeParallellogram(b2Vec2* pos, b2Vec2* size, double alpha, float rotation, Uint8 r, Uint8 g, Uint8 b, Uint8 a) {
    bool success = true;
    short vpx[4], vpy[4];

    int side = size->y / sin(alpha);
    double ady = cos(alpha) * side;

    float angle = rotation * 57;
    SDL_Point center = {(int) pos->x+ (border/2), (int) pos->y+ (border/2)};
    //Calculo los puntos del paralelogramo
    vpx[0] = (pos->x + size->x / 2) + (border/2);
    vpy[0] = (pos->y + size->y / 2)+ (border/2);

    vpx[1] = (pos->x + size->x / 2 + ady)+ (border/2);
    vpy[1] = (pos->y - size->y / 2)+ (border/2);

    vpx[2] = (pos->x - size->x / 2 + ady)+ (border/2);
    vpy[2] = (pos->y - size->y / 2)+ (border/2);
    

    vpx[3] = (pos->x - size->x / 2)+ (border/2);
    vpy[3] = (pos->y + size->y / 2)+ (border/2);

    SDL_Texture* mTexture = SDL_CreateTexture(this->gameRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, unitWidth+border, unitHeight+border);
    SDL_SetRenderTarget(this->gameRenderer, mTexture);
    //    SDL_SetRenderDrawBlendMode(this->gameRenderer, SDL_BLENDMODE_BLEND);
    SDL_SetTextureBlendMode(mTexture, SDL_BLENDMODE_BLEND);
    SDL_SetRenderDrawColor(this->gameRenderer, 0xFF, 0xFF, 0xAA, SDL_BLENDMODE_NONE);
    SDL_RenderClear(this->gameRenderer);
    if (filledPolygonRGBA(this->gameRenderer, vpx, vpy, 4, r, g, b, a) < 0) {
        string lineToLog = "";
        string error(SDL_GetError());
        lineToLog = "[2] SDL no pudo dibujar el paralelogramo. Error: " + error + "\n";
        myLogFile->writeInLog(2, lineToLog);
        success = false;
    } else {
        SDL_SetRenderTarget(this->gameRenderer, NULL);
        SDL_Texture* mTexture2 = SDL_CreateTexture(this->gameRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, unitWidth+border, unitHeight+border);
        SDL_SetRenderTarget(this->gameRenderer, mTexture2);
        //        SDL_SetRenderDrawBlendMode(this->gameRenderer, SDL_BLENDMODE_BLEND);
        SDL_SetTextureBlendMode(mTexture2, SDL_BLENDMODE_BLEND);
        SDL_SetRenderDrawColor(this->gameRenderer, 0xFF, 0xFF, 0xAA, SDL_BLENDMODE_NONE);
        SDL_RenderClear(this->gameRenderer);
        SDL_RenderCopyEx(this->gameRenderer, mTexture, NULL, NULL, angle, &center, SDL_FLIP_NONE);
        SDL_SetRenderTarget(this->gameRenderer, NULL);
//        SDL_RenderCopyEx(this->gameRenderer, mTexture2, NULL, NULL, 0, &center, SDL_FLIP_NONE);
      SDL_RenderCopy(this->gameRenderer, mTexture2, &viewport, NULL);
          SDL_DestroyTexture(mTexture2);
        mTexture2 = NULL;
    }
    SDL_DestroyTexture(mTexture);
    mTexture = NULL;
    return success;
}

bool SkinFactory::makeTrapezium(b2Vec2* pos, b2Vec2* size, double alpha, double beta, float rotation, Uint8 r, Uint8 g, Uint8 b, Uint8 a) {
    bool success = true;
    short vtx[4], vty[4];

    float angle = rotation * 57;
    SDL_Point center = {(int) pos->x+ (border/2), (int) pos->y+ (border/2)};

    short adyAlpha = size->y / tan(alpha);
    short adyBeta = size->y / tan(beta);

    vtx[0] = (pos->x - size->x / 2)+ (border/2);
    vty[0] = (pos->y + size->y / 2)+ (border/2);

    vtx[1] = (pos->x + size->x / 2)+ (border/2);
    vty[1] = (pos->y + size->y / 2)+ (border/2);

    vtx[2] = (pos->x + size->x / 2 - adyBeta)+ (border/2);
    vty[2] = (pos->y - size->y / 2)+ (border/2);

    vtx[3] = (pos->x - size->x / 2 + adyAlpha)+ (border/2);
    vty[3] = (pos->y - size->y / 2)+ (border/2);
    
    SDL_Texture* mTexture = SDL_CreateTexture(this->gameRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, unitWidth+border, unitHeight+border);
    SDL_SetRenderTarget(this->gameRenderer, mTexture);
    //    SDL_SetRenderDrawBlendMode(this->gameRenderer, SDL_BLENDMODE_BLEND);
    SDL_SetTextureBlendMode(mTexture, SDL_BLENDMODE_BLEND);
    SDL_SetRenderDrawColor(this->gameRenderer, 0xFF, 0xFF, 0xAA, SDL_BLENDMODE_NONE);
    SDL_RenderClear(this->gameRenderer);
    if (filledPolygonRGBA(this->gameRenderer, vtx, vty, 4, r, g, b, a) < 0) {
        string lineToLog = "";
        string error(SDL_GetError());
        lineToLog = "SDL no pudo dibujar el trapecio. Error: " + error + "\n";
        myLogFile->writeInLog(2, lineToLog);
        success = false;
    } else {
        SDL_SetRenderTarget(this->gameRenderer, NULL);
        SDL_Texture* mTexture2 = SDL_CreateTexture(this->gameRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, unitWidth+border, unitHeight+border);
        SDL_SetRenderTarget(this->gameRenderer, mTexture2);
        //        SDL_SetRenderDrawBlendMode(this->gameRenderer, SDL_BLENDMODE_BLEND);
        SDL_SetTextureBlendMode(mTexture2, SDL_BLENDMODE_BLEND);
        SDL_SetRenderDrawColor(this->gameRenderer, 0xFF, 0xFF, 0xAA, SDL_BLENDMODE_NONE);
        SDL_RenderClear(this->gameRenderer);
        SDL_RenderCopyEx(this->gameRenderer, mTexture, NULL, NULL, angle, &center, SDL_FLIP_NONE);
        SDL_SetRenderTarget(this->gameRenderer, NULL);
//        SDL_RenderCopyEx(this->gameRenderer, mTexture2, NULL, NULL, 0, &center, SDL_FLIP_NONE);
        SDL_RenderCopy(this->gameRenderer, mTexture2, &viewport, NULL);
        SDL_DestroyTexture(mTexture2);
        mTexture2 = NULL;
    }
    SDL_DestroyTexture(mTexture);
    mTexture = NULL;
    return success;
}
